package com.itlong.cloud.controller.sdkV2.intercom.server;

import com.alibaba.fastjson.JSON;
import com.itlong.cloud.POJO.DTO.property.*;
import com.itlong.cloud.POJO.DTO.sdk.*;
import com.itlong.cloud.POJO.PO.AppUserRoomPO;
import com.itlong.cloud.POJO.PO.AppVisitorPassCodeRecordPO;
import com.itlong.cloud.POJO.PO.ProjectPO;
import com.itlong.cloud.POJO.VO.MessageVO;
import com.itlong.cloud.POJO.VO.SDKMessageVO;
import com.itlong.cloud.POJO.VO.app.AppGetQrcodeVO;
import com.itlong.cloud.POJO.VO.property.PropertyEquipRecordGetVO;
import com.itlong.cloud.POJO.VO.sdk.*;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.annotation.LoggerInfo;
import com.itlong.cloud.annotation.UnAuthAccessRequired;
import com.itlong.cloud.constants.LogDescConstant;
import com.itlong.cloud.enumerate.AppUserProjectStatusEnum;
import com.itlong.cloud.enumerate.AppUserRoomHouserTypeEnum;
import com.itlong.cloud.enumerate.HouseHoldJPushSceneTypeEnum;
import com.itlong.cloud.enumerate.SmartCommunityEnum;
import com.itlong.cloud.enumerate.ecode.*;
import com.itlong.cloud.equip.app.IAppDeviceServiceClient;
import com.itlong.cloud.equip.property.IPropertyEquipRecordServiceClient;
import com.itlong.cloud.equip.sdk.ICloudTalkSDKServiceClient;
import com.itlong.cloud.project.app.IAppRoomServiceClient;
import com.itlong.cloud.project.operate.IOperateProjectServiceClient;
import com.itlong.cloud.project.sdk.ICloudTalkSDKServerProjectServiceClient;
import com.itlong.cloud.project.sdk.ISDKServerProjectServiceClient;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.user.app.IAppMineServiceClient;
import com.itlong.cloud.user.app.IAppRegisterServiceClient;
import com.itlong.cloud.user.operate.IOperatePropertyAccountServiceClient;
import com.itlong.cloud.user.property.IPropertyHouseHoldInfoServiceClient;
import com.itlong.cloud.user.sdk.ICloudTalkSDKServerUserServiceClient;
import com.itlong.cloud.user.sdk.ISDKServerOldUserServiceClient;
import com.itlong.cloud.utils.encrypt.Md5EncryptUtil;
import com.itlong.cloud.utils.network.http.HttpProtocolUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * <desc>
 * 云对讲SDK服务端用户信息Controller
 * </desc>
 *
 * @createDate 2018/05/11
 */
@RestController
@RequestMapping("/sdk/cloud/intercom/server")
public class SDKCloudTalkUserController {

    private static final Logger LOG = LoggerFactory.getLogger(SDKCloudTalkUserController.class);

    @Value("${" + PlatformConstants.CLOUDTALK_SDK_USER_TOKEN_KEY + "}")
    private String CLOUDTALK_SDK_USER_TOKEN_KEY;

    @Autowired
    ICloudTalkSDKServerUserServiceClient iCloudTalkSDKServerUserServiceClient;

    @Autowired
    IOperatePropertyAccountServiceClient iOperatePropertyAccountServiceClient;

    @Autowired
    ISDKServerOldUserServiceClient iSDKServerUserServiceClient;

    @Autowired
    private ICloudTalkSDKServerProjectServiceClient iCloudTalkSDKServerProjectServiceClient;

    @Autowired
    private IAppDeviceServiceClient iAppDeviceServiceClient;

    @Autowired
    private IAppMineServiceClient iAppMineServiceClient;

    @Autowired
    IAppRegisterServiceClient iAppRegisterServiceClient;

    @Autowired
    IAppRoomServiceClient iAppRoomServiceClient;

    @Autowired
    ICloudTalkSDKServiceClient iCloudTalkSDKServiceClient;

    @Autowired
    private IPropertyEquipRecordServiceClient iPropertyEquipRecordServiceClient;

    @Autowired
    IPropertyHouseHoldInfoServiceClient iPropertyHouseHoldInfoServiceClient;

    @Autowired
    ISDKServerProjectServiceClient isdkServerProjectServiceClient;

    @Autowired
    IOperateProjectServiceClient iOperateProjectServiceClient;


    /**
     * <desc>
     *      设置业主二维码
     * </desc>
     *
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2018/11/20
     */
    @ResponseBody
    @PostMapping(path = "/setOwnerQrCode")
    @LoggerInfo(operateDesc = LogDescConstant.SDK_SERVER_SET_OWNER_QR_CODE_LOG_DESC)
    public Object setOwnerQrCode(){
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            CloudTalkSDKServerOwnerQrCodeDTO cloudTalkSDKServerOwnerQrCodeDTO = HttpProtocolUtil.parseRequestParamToDTO(CloudTalkSDKServerOwnerQrCodeDTO.class, request);
            String appId = cloudTalkSDKServerOwnerQrCodeDTO.getAppId();
            String responseTimestamp = new Date().getTime()+"";
            LOG.info("====云对讲SDK设置业主二维码入参：appid:" + appId + " projectId:" + cloudTalkSDKServerOwnerQrCodeDTO.getProjectId() + " userId:" + cloudTalkSDKServerOwnerQrCodeDTO.getUserId());
            String projectId = cloudTalkSDKServerOwnerQrCodeDTO.getProjectId();
            // 解密项目id
//            projectId = DesEncryptUtil.projectIdDesEncrypt(projectId) == null ? projectId : DesEncryptUtil.projectIdDesEncrypt(projectId);
            // 校验开发者账号是否有该项目的权限
            List<String> projectIdList = iCloudTalkSDKServerUserServiceClient.getProjectIdByParams(appId);
            if (projectIdList == null || projectIdList.isEmpty() || !projectIdList.contains(projectId)) {
                return new SDKMessageVO(CloudTalkErrorCodeEnum.SERVER_CHECKDEVELOPER_AUTH.getErrorCode(),cloudTalkSDKServerOwnerQrCodeDTO.getRequestId(),responseTimestamp,"");
            }

            //校验该用户是否被禁用
            if(iAppRegisterServiceClient.getUserStatusByProjectId(cloudTalkSDKServerOwnerQrCodeDTO.getUserId(),projectId) == 0){
                ErrorCode errorCode = CloudTalkErrorCodeEnum.SERVER_SDK_USER_ACCOUNT_ERR.getErrorCode();
                return new SDKMessageVO(errorCode, cloudTalkSDKServerOwnerQrCodeDTO.getRequestId(), responseTimestamp, "");
            }

            // 更新用户二维码
            iAppDeviceServiceClient.setUserQrCode(cloudTalkSDKServerOwnerQrCodeDTO.getUserId(),projectId,null);
            AppGetQrcodeVO userQrcode = iAppMineServiceClient.getUserQrcode(projectId, cloudTalkSDKServerOwnerQrCodeDTO.getUserId(),null);
            Map<String,String> map = new HashMap<>();
            map.put("qrcodeStr",userQrcode.getQrcode());
            //保存生成操作日志所需信息 详细描述和接口类别
            request.setAttribute("remark",projectId + "设置业主二维码");
            request.setAttribute("portType",LogDescConstant.SDK_CLOUD_TALK_TYPE_LOG_DESC);

            Map<String, Object> signMap = new HashMap<>();
            signMap.put("data", JSON.toJSONString(map));
            return new SDKMessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), cloudTalkSDKServerOwnerQrCodeDTO.getRequestId(), responseTimestamp,
                    Md5EncryptUtil.getSDKV2Md5(signMap,cloudTalkSDKServerOwnerQrCodeDTO.getRequestId(),responseTimestamp, request.getAttribute("appSecret").toString()), map);

        } catch (Exception e) {
            throw new DataAccessException("【云对讲SDK_服务端_用户服务】设置业主二维码失败",e);
        }
    }

    /**
     * <desc>
     *      设置开门密码
     * </desc>
     *
     * @return
     * @author Juguang.S
     * @createDate 2018/11/21
     */
    @PostMapping("/setOpenPwd")
    @LoggerInfo(operateDesc = LogDescConstant.SDK_SERVER_SET_OPEN_PWD_LOG_DESC)
    @ResponseBody
    public Object setDoorPwd(){
        SDKMessageVO messageVO;
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            CloudTalkSDKServerOpenPwdDTO openPwdDTO = HttpProtocolUtil.parseRequestParamToDTO(CloudTalkSDKServerOpenPwdDTO.class, request);
            String userId = openPwdDTO.getUserId();
            String openPwd = openPwdDTO.getOpenPwd();
            String projectId = openPwdDTO.getProjectId();
            String appId = openPwdDTO.getAppId();
            String responseTimestamp = new Date().getTime() + "";
            openPwdDTO.setResponseTimestamp(responseTimestamp);
            LOG.info("====云对讲SDK设置开门密码入参：appid:" + appId + " projectId:" + projectId + " userId:" + userId + " openPwd:" + openPwd);
            // 解密项目id
            //projectId = DesEncryptUtil.projectIdDesEncrypt(projectId) == null ? projectId : DesEncryptUtil.projectIdDesEncrypt(projectId);
            // 校验开发者账号是否有该项目的权限
            List<String> projectIdList = iCloudTalkSDKServerUserServiceClient.getProjectIdByParams(appId);
            String projectStr = null;
            if(!projectIdList.isEmpty() && projectIdList!=null){
                projectStr = String.join(",",projectIdList);
            }
            if(!projectStr.contains(projectId)){
                return new SDKMessageVO(CloudTalkErrorCodeEnum.SERVER_CHECKDEVELOPER_AUTH.getErrorCode(), openPwdDTO.getRequestId(), openPwdDTO.getResponseTimestamp(), "");
            }

            if (StringUtils.isBlank(projectId) || StringUtils.isBlank(openPwd) || StringUtils.isBlank(userId)){
                return new SDKMessageVO(CloudTalkErrorCodeEnum.NOT_PARAM.getErrorCode(), openPwdDTO.getRequestId(), openPwdDTO.getResponseTimestamp(), "");
            }else if(!openPwd.matches("[0-9]{4}")){
                ErrorCode errorCode =AppErrorCodeEnum.OPEN_PASSWORD_IS_ERROR.getErrorCode();
                return new SDKMessageVO(errorCode, openPwdDTO.getRequestId(), openPwdDTO.getResponseTimestamp(), "");
            }

            //检查用户是否是业主
            if(iAppRegisterServiceClient.countUserAttacheInfoInProject(userId,projectId) < 1){
                ErrorCode errorCode = AppErrorCodeEnum.USER_NOT_OWNER.getErrorCode();
                return new SDKMessageVO(errorCode, openPwdDTO.getRequestId(), openPwdDTO.getResponseTimestamp(), "");
            }
            //校验该用户是否被禁用
            if(iAppRegisterServiceClient.getUserStatusByProjectId(userId,projectId) == 0){
                ErrorCode errorCode = CloudTalkErrorCodeEnum.SERVER_SDK_USER_ACCOUNT_ERR.getErrorCode();
                return new SDKMessageVO(errorCode, openPwdDTO.getRequestId(), openPwdDTO.getResponseTimestamp(), "");
            }

            iAppRoomServiceClient.setOpenPwd(projectId,userId,openPwd);
            //推送设备拉取业主信息
            iAppDeviceServiceClient.pushCloudDeviceAuth(projectId,userId,
                    SmartCommunityEnum.PUSH_ROOM.getCommandType());
            ErrorCode errorCode =BaseErrorCodeEnum.SUCCESS.getErrorCode();
            messageVO=new SDKMessageVO(errorCode, openPwdDTO.getRequestId(), openPwdDTO.getResponseTimestamp(), "");
            //保存生成操作日志所需信息 详细描述和接口类别
            request.setAttribute("remark",LogDescConstant.SDK_SERVER_SET_OPEN_PWD_LOG_DESC);
            request.setAttribute("portType",LogDescConstant.SDK_CLOUD_TALK_TYPE_LOG_DESC);
        }catch (Exception e){
            throw new DataAccessException("【云对讲SDK_server_setDoorPwd】设置开门密码失败",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      设置访客动态密码
     * </desc>
     *
     * @return
     * @author Juguang.S
     * @createDate 2018/11/24
     */
    @PostMapping(path = "/server/getVisitorQrCode")
    @LoggerInfo(operateDesc = LogDescConstant.SDK_SERVER_SET_VISITOR_DYPWD_LOG_DESC)
    @ResponseBody
    public Object getVisitorQrCode(){
        try{
            HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
            CloudTalkSDKServerVisitorPwdDTO visitorPwdDTO = HttpProtocolUtil.parseRequestParamToDTO(CloudTalkSDKServerVisitorPwdDTO.class, request);
            String appId = visitorPwdDTO.getAppId();
            String projectId = visitorPwdDTO.getProjectId();
            String userId = visitorPwdDTO.getUserId();
            String buildNum = visitorPwdDTO.getBuildNum();
            String unitNum = visitorPwdDTO.getUnitNum();
            String visitorName = visitorPwdDTO.getVisitorName();
            String visitorPhone = visitorPwdDTO.getVisitorPhone();
            String floorNum = visitorPwdDTO.getFloorNum();
            String effectiveTime = visitorPwdDTO.getEffectiveTime();
            String viladType = visitorPwdDTO.getViladType();

            if(StringUtils.isEmpty(projectId) || StringUtils.isEmpty(userId)
                    || StringUtils.isEmpty(buildNum) || StringUtils.isEmpty(unitNum) || StringUtils.isEmpty(visitorName)
                    || StringUtils.isEmpty(visitorPhone) || StringUtils.isEmpty(floorNum) || StringUtils.isEmpty(effectiveTime) || StringUtils.isEmpty(viladType)){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            if(Integer.parseInt(effectiveTime)>1440){
                return new MessageVO(CloudTalkErrorCodeEnum.SERVER_SDK_DYPWD_ERR.getErrorCode());
            }
            LOG.info("云对讲SDK设置访客动态密码入参：appid:" + appId + " projectId:" + projectId + " userId:" + userId);
            // 解密项目id
            //projectId = DesEncryptUtil.projectIdDesEncrypt(projectId) == null ? projectId : DesEncryptUtil.projectIdDesEncrypt(projectId);

            //校验buildNum unitNum 该项目下是否有该单元信息
            visitorPwdDTO.setProjectId(projectId);
            if(iCloudTalkSDKServerUserServiceClient.getExistBuildInfo(visitorPwdDTO)==null){
                return new MessageVO(CloudTalkErrorCodeEnum.SERVER_NOT_EXIST_BUILDNUM_ERR.getErrorCode());
            }

            //根据ProjectId,buildNum查询出该楼栋的最高楼层
            if(iCloudTalkSDKServerUserServiceClient.getBuildFloorNum(projectId,buildNum)<Integer.parseInt(floorNum)){
                return new MessageVO(CloudTalkErrorCodeEnum.SERVER_SDK_FLOORNUM_ERR.getErrorCode());
            }

            // 校验开发者账号是否有该项目的权限
            List<String> projectIdList = iCloudTalkSDKServerUserServiceClient.getProjectIdByParams(appId);
            String projectStr = null;
            if(!projectIdList.isEmpty() && projectIdList!=null){
                projectStr = String.join(",",projectIdList);
            }
            if(!projectStr.contains(projectId)){
                return new MessageVO(CloudTalkErrorCodeEnum.SERVER_CHECKDEVELOPER_AUTH.getErrorCode());
            }
            AppVisitorPassCodeRecordPO passPO = iCloudTalkSDKServerUserServiceClient.getVisitorPwdAndQrCode(visitorPwdDTO);
            Map<String,String> returnMap =  new HashMap<>();
            returnMap.put("password",passPO.getPassword());
            returnMap.put("qrcodeStr",passPO.getQrcode());
            //保存生成操作日志所需信息 详细描述和接口类别
            request.setAttribute("remark",LogDescConstant.SDK_SERVER_SET_VISITOR_DYPWD_LOG_DESC);
            request.setAttribute("portType",LogDescConstant.SDK_CLOUD_TALK_TYPE_LOG_DESC);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),returnMap);
        }catch (Exception e){
            throw new DataAccessException("【云对讲SDK_server_getVisitorQrCode】设置访客动态密码失败",e);
        }
    }

    /**
     * <desc>
     *      查询通行记录
     * </desc>
     *
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2018/11/20
     */
    @UnAuthAccessRequired
    public Object getPassRecord(CloudDeviceSDKDTO dto) throws Exception {
        // 处理参数
        if (StringUtils.isEmpty(dto.getPageSize() )) {
            dto.setPageSize("15");
        }
        if (StringUtils.isEmpty(dto.getCurrentPage())) {
            dto.setCurrentPage("1");
        }
        PropertyEquipRecordGetDTO propertyEquipRecordGetDTO = new PropertyEquipRecordGetDTO();
        BeanUtils.copyProperties(dto, propertyEquipRecordGetDTO);
        propertyEquipRecordGetDTO.setRealName(dto.getName());
        propertyEquipRecordGetDTO.setCurrentPage(dto.getPageSize());
        dto.setDeviceType("3");
        dto.setRecordType("3");
        Page<SDKEquipRecordGetVO> page = isdkServerProjectServiceClient.getPassRecordByPage(dto);
        return new SDKMessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),dto.getRequestId(),dto.getResponseTimestamp(),
                Md5EncryptUtil.getSDKV2Md5(new HashMap<>(),dto.getRequestId(),dto.getResponseTimestamp(),dto.getAppSecret()), page);
    }

    /**
     * <desc>
     * 查询用户列表
     * <desc/>
     *
     * @return MessageVO 标准格式化响应结果
     * @author Juguang.S
     * @createDate 2020/11/22
     */
    @RequestMapping(path = "/getUserInfo", method = RequestMethod.POST)
    @ResponseBody
    public Object getUserInfo() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        try {
            CloudFaceApiDTO dto = HttpProtocolUtil.parseRequestParamToDTO(CloudFaceApiDTO.class, request);

            String responseTimestamp = new Date().getTime() + "";
            if (StringUtils.isEmpty(dto.getProjectId())) {
                return new SDKMessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode(), dto.getRequestId(), responseTimestamp, "");
            }
            dto.setPageSize(request.getAttribute("pageSize") == null ? null : request.getAttribute("pageSize").toString());
            dto.setCurrentPage(request.getAttribute("currentPage") == null ? null : request.getAttribute("currentPage").toString());
            if (StringUtils.isBlank(dto.getCurrentPage())) {
                dto.setCurrentPage("1");
            }
            if (StringUtils.isBlank(dto.getPageSize())) {
                dto.setPageSize("15");
            }

            Page<SDKFaceUserInfoGetVO> result = iPropertyHouseHoldInfoServiceClient.getUserInfoForApi(dto);
            Page<SDKUserInfoGetAssembleByCloudTalkVO> page = new Page<>();
            page.setPage(result.getPage());
            page.setRows(this.assembleApiUserInfoGetVO(result.getRows()));
            return new SDKMessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), dto.getRequestId(), dto.getResponseTimestamp(),
                    Md5EncryptUtil.getSDKV2Md5(new HashMap<>(), dto.getRequestId(), dto.getResponseTimestamp(), dto.getAppSecret()), page);
        } catch (Exception e) {
            request.setAttribute("exception", e.toString());
            throw new DataAccessException("【SDK_云对讲API_getUserInfo】查询用户列表异常", e);
        }
    }

    /**
     * <desc>
     * 组装查询用户信息返回
     * <desc/>
     *
     * @param sdkFaceUserInfoGetVOS 住户信息对象
     * @return List<SDKUserInfoGetAssembleVO> 组装过的物业住户信息
     * @author Juguang.S
     * @createDate 2020/11/22
     */
    private List<SDKUserInfoGetAssembleByCloudTalkVO> assembleApiUserInfoGetVO(List<SDKFaceUserInfoGetVO> sdkFaceUserInfoGetVOS) {
        //返回结果
        List<SDKUserInfoGetAssembleByCloudTalkVO> sdkUserInfoGetAssembleVOS = new ArrayList<>();
        //用于组装合并数据
        LinkedHashMap<String, SDKUserInfoGetAssembleByCloudTalkVO> linkedHashMap = new LinkedHashMap<>();
        //记录住户
        LinkedHashSet<String> userIdSet = new LinkedHashSet<>();
        if (sdkFaceUserInfoGetVOS.isEmpty()) {
            return sdkUserInfoGetAssembleVOS;
        }
        //遍历
        for (SDKFaceUserInfoGetVO sdkFaceUserInfoGetVO : sdkFaceUserInfoGetVOS) {
            String userId = sdkFaceUserInfoGetVO.getUserId();
            userIdSet.add(userId);
            //相同住户合并住户房间信息
            if (linkedHashMap.get(userId) == null) {
                List<SDKUserInfoGetRoomByCloudTalkVO> sdkUserInfoGetRoomVOS = new ArrayList<>();
                SDKUserInfoGetRoomByCloudTalkVO sdkUserInfoGetRoomVO = new SDKUserInfoGetRoomByCloudTalkVO();
                BeanUtils.copyProperties(sdkFaceUserInfoGetVO, sdkUserInfoGetRoomVO);
                sdkUserInfoGetRoomVOS.add(sdkUserInfoGetRoomVO);
                SDKUserInfoGetAssembleByCloudTalkVO sdkUserInfoGetAssembleVO =
                        new SDKUserInfoGetAssembleByCloudTalkVO(userId, sdkFaceUserInfoGetVO.getRealName(), sdkFaceUserInfoGetVO.getPhoneNum(),
                                sdkFaceUserInfoGetVO.getGender(), sdkFaceUserInfoGetVO.getFacePicUrl(), sdkFaceUserInfoGetVO.getFaceCreateTime(),
                                sdkFaceUserInfoGetVO.getIsFace(), sdkUserInfoGetRoomVOS);
                sdkUserInfoGetAssembleVO.setClientToken(sdkFaceUserInfoGetVO.getClientToken());
                linkedHashMap.put(userId, sdkUserInfoGetAssembleVO);
            } else {
                SDKUserInfoGetAssembleByCloudTalkVO sdkUserInfoGetAssembleVO = linkedHashMap.get(userId);
                List<SDKUserInfoGetRoomByCloudTalkVO> sdkUserInfoGetRoomVOS = sdkUserInfoGetAssembleVO.getUserRoomInfoS();
                SDKUserInfoGetRoomByCloudTalkVO sdkUserInfoGetRoomVO = new SDKUserInfoGetRoomByCloudTalkVO();
                BeanUtils.copyProperties(sdkFaceUserInfoGetVO, sdkUserInfoGetRoomVO);
                sdkUserInfoGetRoomVOS.add(sdkUserInfoGetRoomVO);
                sdkUserInfoGetAssembleVO.setUserRoomInfoS(sdkUserInfoGetRoomVOS);
                linkedHashMap.put(userId, sdkUserInfoGetAssembleVO);
            }
        }
        for (String userId : userIdSet) {
            sdkUserInfoGetAssembleVOS.add(linkedHashMap.get(userId));
        }
        return sdkUserInfoGetAssembleVOS;
    }

    /**
     * <desc>
     * 用户迁入
     * <desc/>
     *
     * @return Object   标准格式化响应结果
     * @author Juguang.S
     * @createDate 2021/06/15
     */
    @ResponseBody
    @RequestMapping("/userMoveIn")
    @LoggerInfo(operateDesc = LogDescConstant.SDK_FACE_USER_MOVE_IN_LOG_DESC)
    public Object userMoveIn() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        try {
            String responseTimestamp = new Date().getTime() + "";
            if (request.getAttribute("appUsersMovein") == null || request.getAttribute("projectId") == null) {
                return new SDKMessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode(), request.getAttribute("requestId").toString(), responseTimestamp, "");
            }
            String appUsersMovein = request.getAttribute("appUsersMovein").toString();
            String projectId = request.getAttribute("projectId").toString();
            //保存生成操作日志所需信息 详细描述和接口类别
            request.setAttribute("remark", appUsersMovein + "|" + projectId);
            request.setAttribute("portType", LogDescConstant.SDK_CLOUD_FACE_RECOGNITION_TYPE_LOG_DESC);
            //解析传入的需迁入的App用户信息
            AppUserUpdateUserRoomStatusDTO appUserUpdateUserRoomStatusDTO;
            try {
                appUserUpdateUserRoomStatusDTO = JSON.parseObject(appUsersMovein, AppUserUpdateUserRoomStatusDTO.class);
            } catch (Exception e) {
                return new SDKMessageVO(SDKErrorCodeEnum.SDK_INPUT_PARAM_ERR.getErrorCode(), request.getAttribute("requestId").toString(), responseTimestamp, "");
            }
            appUserUpdateUserRoomStatusDTO.setProjectId(projectId);
            List<AppUsersRemoveDTO> appUsersRemoveDTOS = appUserUpdateUserRoomStatusDTO.getAppUsersRemoveDTOList();
            if (appUsersRemoveDTOS.isEmpty()) {
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_USERROOM_NOT_NULL.getErrorCode(), request.getAttribute("requestId").toString(), responseTimestamp, "");
            }
            //查询当前项目信息
            ProjectPO projectPO = iOperateProjectServiceClient.getOneProject(projectId);
            //是否启用云对讲，默认0,0-否，1-是
            Integer isSmartCommunity = projectPO.getIsSmartCommunity();
            //住宅最大授权数，最大为10
            Integer authMaxNum = projectPO.getAuthMaxNum();
            //办公最大授权数，最大为500
            Integer officeAuthMaxNum = projectPO.getOfficeAuthMaxNum();
            if (officeAuthMaxNum == 0) {
                officeAuthMaxNum = 11;
            }
            //判断迁入住户业主房间地址中是否已存在业主
            Set<String> userIds = new HashSet<>();
            for (AppUsersRemoveDTO appUsersRemoveDTO : appUsersRemoveDTOS) {
                //住户userId
                String userId = appUsersRemoveDTO.getUserId();
                //住户项目数据状态正常时，若住户已被冻结，则无法迁入
                Integer userProjectStatus = iPropertyHouseHoldInfoServiceClient.getUserProjectStatusAtNormal(projectId, userId);
                if (AppUserProjectStatusEnum.USERPROJECT_USERPROJECTSTATUS_FROZEN.getType() == userProjectStatus) {
                    return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_USERPROJECTSTATUS_FROZEN.getErrorCode(), request.getAttribute("requestId").toString(), responseTimestamp, "");
                }
                List<AppUserRoomDTO> appUserRoomDTOS = appUsersRemoveDTO.getAppUserRoomDTOS();
                //由于云对讲SDK对外 需要传入buildNum unitNum等，故在此需转换为buildId unitId等
                for(AppUserRoomDTO roomDTO : appUserRoomDTOS){
                    roomDTO.setProjectId(projectId);
                    AppUserRoomDTO roomInfo = iPropertyHouseHoldInfoServiceClient.getRoomInfo(roomDTO);
                    if(roomInfo!=null){
                        roomDTO.setBuildId(roomInfo.getBuildId());
                        roomDTO.setUnitId(roomInfo.getUnitId());
                        roomDTO.setRoomId(roomInfo.getRoomId());
                    }
                }
                //Map<String, value> ：isExist业主是否存在，roomNum 业主存在时的房间号,userId 业主userId
                Map<String, String> resultMap = this.checkOwnerExist(appUserRoomDTOS);
                String isExist = resultMap.get("isExist");
                //房间存在业主，且房间中的业主与当前用户不是同一人时才不允许添加
                if (StringHandlerUtil.compareStrWithOutEmpty("true", isExist) &&
                        !StringHandlerUtil.compareStrWithOutEmpty(userId, resultMap.get("userId"))) {
                    String roomNum = resultMap.get("roomNum");
                    return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_USERPROJECTSTATUS_FROZEN.getErrorCode(), roomNum + ",该房间下已有业主或管理员", request.getAttribute("requestId").toString(), responseTimestamp, "", isExist);
                }
                //获取住户要添加的房间中已入住的用户人数，再跟项目中设置好的房间最大人数比较，超过则不允许添加
                for (AppUserRoomDTO appUserRoomDTO : appUserRoomDTOS) {
                    //当前房间中的住户数量
                    Integer currentExistCount =
                            iPropertyHouseHoldInfoServiceClient.getMoveInHouseHoldCount(appUserRoomDTO.getRoomId(), projectId);
                    //获取该房屋类型 1住宅 2办公
                    Integer housesType = iPropertyHouseHoldInfoServiceClient.getHousesType(appUserRoomDTO.getRoomId(), projectId);
                    //已达到或超过项目中最大授权人数则无法添加住户
                    if (housesType == 1 && currentExistCount >= authMaxNum) {
                        return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_USERPROJECTSTATUS_FROZEN.getErrorCode(), String.format("%s房间中住户人数已达上限", appUserRoomDTO.getRoomNum()), request.getAttribute("requestId").toString(), responseTimestamp, "");
                    }
                    if (housesType == 3 && currentExistCount >= officeAuthMaxNum) {
                        return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_USERPROJECTSTATUS_FROZEN.getErrorCode(), String.format("%s房间中住户人数已达上限", appUserRoomDTO.getRoomNum()), request.getAttribute("requestId").toString(), responseTimestamp, "");
                    }
                }
                userIds.add(userId);
            }

            //迁入App用户信息
            iPropertyHouseHoldInfoServiceClient.userMoveIn(appUserUpdateUserRoomStatusDTO, isSmartCommunity,
                    request.getAttribute("appId").toString(), HouseHoldJPushSceneTypeEnum.HOUSEHOLD_J_PUSH_SCENE_TYPE_MOVE_IN.getType());
            return new SDKMessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), request.getAttribute("requestId").toString(), responseTimestamp,
                    Md5EncryptUtil.getSDKV2Md5(new HashMap<>(), request.getAttribute("requestId").toString(), responseTimestamp,
                            request.getAttribute("appSecret").toString()));
        } catch (Exception e) {
            request.setAttribute("exception", e.toString());
            throw new DataAccessException("【SDK_人脸识别API_userMoveIn】用户迁入异常", e);
        }
    }

    /**
     * <desc>
     * 用户迁出
     * <desc/>
     *
     * @return Object   标准格式化响应结果
     * @author Qiang.S
     * @createDate 2019/11/05
     */
    @ResponseBody
    @RequestMapping("/userRemove")
    @LoggerInfo(operateDesc = LogDescConstant.SDK_FACE_USER_REMOVE_LOG_DESC)
    public Object userRemove() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        try {
            String responseTimestamp = new Date().getTime() + "";
            if (request.getAttribute("appUsersRemove") == null || request.getAttribute("projectId") == null) {
                return new SDKMessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode(), request.getAttribute("requestId").toString(), responseTimestamp, "");
            }
            String appUsersRemove = request.getAttribute("appUsersRemove").toString();
            String projectId = request.getAttribute("projectId").toString();
            //保存生成操作日志所需信息 详细描述和接口类别
            request.setAttribute("remark", appUsersRemove + "|" + projectId);
            request.setAttribute("portType", LogDescConstant.SDK_CLOUD_FACE_RECOGNITION_TYPE_LOG_DESC);
            //解析JSON数据
            AppUserUpdateUserRoomStatusDTO appUserUpdateUserRoomStatusDTO;
            try {
                appUserUpdateUserRoomStatusDTO = JSON.parseObject(appUsersRemove, AppUserUpdateUserRoomStatusDTO.class);
            } catch (Exception e) {
                return new SDKMessageVO(SDKErrorCodeEnum.SDK_INPUT_PARAM_ERR.getErrorCode(), request.getAttribute("requestId").toString(), responseTimestamp, "");
            }
            //迁出用户信息不能为空
            if (appUserUpdateUserRoomStatusDTO == null) {
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_USERREMEVO_NOT_NULL.getErrorCode(), request.getAttribute("requestId").toString(), responseTimestamp, "");
            }
            List<AppUsersRemoveDTO> appUsersRemoveDTOS = appUserUpdateUserRoomStatusDTO.getAppUsersRemoveDTOList();
            if (appUsersRemoveDTOS == null || appUsersRemoveDTOS.size() < 1) {
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_USERROOM_NOT_NULL.getErrorCode(), request.getAttribute("requestId").toString(), responseTimestamp, "");
            }
            Set<String> userIds = new HashSet<>();
            for (AppUsersRemoveDTO appUsersRemoveDTO : appUsersRemoveDTOS) {
                String userId = appUsersRemoveDTO.getUserId();
                //住户项目数据状态正常时，若住户已被冻结，则无法迁入
                Integer userProjectStatus = iPropertyHouseHoldInfoServiceClient.getUserProjectStatusAtNormal(projectId, userId);
                if (AppUserProjectStatusEnum.USERPROJECT_USERPROJECTSTATUS_FROZEN.getType() == userProjectStatus) {
                    return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_USERPROJECTSTATUS_FROZEN.getErrorCode(), request.getAttribute("requestId").toString(), responseTimestamp, "");
                }
                userIds.add(userId);

                //由于云对讲SDK对外 需要传入buildNum unitNum等，故在此需转换为buildId unitId等
                for(AppUserRoomDTO roomDTO : appUsersRemoveDTO.getAppUserRoomDTOS()){
                    roomDTO.setProjectId(projectId);
                    AppUserRoomDTO roomInfo = iPropertyHouseHoldInfoServiceClient.getRoomInfo(roomDTO);
                    if(roomInfo!=null){
                        roomDTO.setBuildId(roomInfo.getBuildId());
                        roomDTO.setUnitId(roomInfo.getUnitId());
                        roomDTO.setRoomId(roomInfo.getRoomId());
                    }
                }
            }
            //查询当前项目信息
            ProjectPO projectPO = iOperateProjectServiceClient.getOneProject(projectId);

            //是否使用云对讲： 0-否，1-是
            Integer isSmartCommunity = projectPO.getIsSmartCommunity();

            appUserUpdateUserRoomStatusDTO.setProjectId(projectId);
            appUserUpdateUserRoomStatusDTO.setInstructionType(2);
            appUserUpdateUserRoomStatusDTO.setSourceSystem(4);
            iPropertyHouseHoldInfoServiceClient.userRemove(appUserUpdateUserRoomStatusDTO, isSmartCommunity,
                    request.getAttribute("appId").toString(), HouseHoldJPushSceneTypeEnum.HOUSEHOLD_J_PUSH_SCENE_TYPE_MOVE_OUT.getType());
            return new SDKMessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), request.getAttribute("requestId").toString(), responseTimestamp,
                    Md5EncryptUtil.getSDKV2Md5(new HashMap<>(), request.getAttribute("requestId").toString(), responseTimestamp,
                            request.getAttribute("appSecret").toString()));
        } catch (Exception e) {
            request.setAttribute("exception", e.toString());
            throw new DataAccessException("【SDK_人脸识别API_userRemove】用户迁出异常", e);
        }
    }

    /**
     * <desc>
     * 判断添加住户业主房间地址时房间是否已存在业主
     * <desc/>
     *
     * @param appUserRoomDTOS App用户房间信息传输数据集
     * @return Map<String, String> :
     * Map<String, value> isExist业主是否存在，roomNum 业主存在时的房间号,userId 业主userId
     * @author zhangs
     * @createDate 2017/09/20
     */
    private Map<String, String> checkOwnerExist(List<AppUserRoomDTO> appUserRoomDTOS) {
        Map<String, String> resultMap = new HashMap<>();
        if (appUserRoomDTOS == null || (appUserRoomDTOS.isEmpty())) {
            resultMap.put("isExist", "false");
            return resultMap;
        }
        for (AppUserRoomDTO appUserRoomDTO : appUserRoomDTOS) {
            if (appUserRoomDTO.getHouserType() == AppUserRoomHouserTypeEnum.USERROOM_HOUSERTYPE_OWNER.getType()) {
                AppUserRoomOwnerIsExistDTO appUserRoomOwnerIsExistDTO = new AppUserRoomOwnerIsExistDTO();
                appUserRoomOwnerIsExistDTO.setRoomId(appUserRoomDTO.getRoomId());
                //获取roomId对应房间是否已存在业主
                List<AppUserRoomPO> appUserRoomPOS =
                        iPropertyHouseHoldInfoServiceClient.getExistHouserByRoom(appUserRoomOwnerIsExistDTO);
                if (appUserRoomPOS != null && appUserRoomPOS.size() > 0) {
                    resultMap.put("isExist", "true");
                    resultMap.put("roomNum", appUserRoomDTO.getRoomNum());
                    resultMap.put("userId", appUserRoomPOS.get(0).getUserId());
                    break;
                }
            }
        }
        return resultMap;
    }

}